home *** CD-ROM | disk | FTP | other *** search
/ CD Ware Multimedia 1995 May / cd Ware (Juegos) Epimundo.iso / DOS / PRGMMING / M2PROTOS.ZIP / QCKPACK.MOD < prev    next >
Encoding:
Modula Implementation  |  1991-01-30  |  11.8 KB  |  367 lines

  1. (*# call(o_a_copy => off) *)
  2. (*%F _fdata *)
  3. (*# call(seg_name => null) *)
  4. (*%E *)
  5. (*# module(implementation=>on) *)
  6. (*# data(seg_name => null) *)
  7. IMPLEMENTATION MODULE QCkpack;
  8.  
  9.                      (* This JPI Modula-2 module is part of *)
  10.  
  11.                       (* QC -- a communications program *)
  12.                              (* by Carl Neiburger *)
  13.                               (* 169 N. 25th St.*)
  14.                           (* San Jose, Calif. 95116 *)
  15.  
  16.                          (* CompuServe No. 72336,2257 *)
  17.  
  18. FROM QCcomm IMPORT (* CommOK, *) ComAbort, ComTimedOut, CommRdData, 
  19.      CommRdDataTest, CommWrData, soh;
  20. FROM CRC IMPORT DoKCRC, DoCks;
  21. FROM Lib IMPORT Move, Fill;
  22. FROM QCdisp IMPORT DataRegisters, Packets, DisplayData;
  23. FROM UTIL IMPORT SBITSET;
  24.  
  25. TYPE InitArrayType = ARRAY[1..SIZE(DefType)] OF SHORTCARD;
  26.  
  27. CONST
  28.     MyDefs = DefType(
  29.          (*  1 MaxLength *)     94,             (* even if long used *)
  30.          (*  2 TimeOut *)       15,
  31.          (*  3 NumPad *)         0,
  32.          (*  4 PadChar *)       40C,
  33.          (*  5 EolChar *)       15C,
  34.          (*  6 CntrlQuote *)    CHR(CtlChar),  (* '#' *)
  35.          (*  7 Bit8Quote *)     'Y',           (*  will do if requested *)
  36.          (*  8 CheckType *)     '3',           (*  CRC *)
  37.          (*  9 RepChar *)       '~',
  38.          (* 10 Capas *)         CapasType{LongOK},
  39.          (* 11 Windo *)         0,
  40.          (* 12 HiMaxLen *)      MaxPacketSize DIV 95,
  41.          (* 13 LoMaxLen *)      MaxPacketSize MOD 95);
  42.  
  43.     SixBits = SBITSET{0,1,2,3,4,5};
  44.     SevenBits = SBITSET{0,1,2,3,4,5,6};
  45.     EightBits = SBITSET{0,1,2,3,4,5,6,7};
  46.  
  47. VAR Parity    : SBITSET;
  48.     InitArray : InitArrayType;  (* used to send MyDefs *)
  49.  
  50. PROCEDURE SimpleCheck(Sum: WORD): SHORTCARD;
  51. BEGIN
  52.   RETURN SHORTCARD( 
  53.     SBITSET( SHORTCARD(Sum) + SHORTCARD(Sum) >> 6 ) * SixBits ) + 20H
  54. END SimpleCheck;
  55.  
  56. PROCEDURE SendPacket( Count : CARDINAL;     (* data characters *)
  57.                       Seq   : SHORTCARD;    (* sequence number *)
  58.                       PType : CHAR;
  59.                       Data  : PackPtr);
  60.  VAR
  61.     i,
  62.     Sum       : CARDINAL;
  63.     CheckBytes,
  64.     AChar     : SHORTCARD;
  65.  
  66. PROCEDURE SendAndCheck( c : BYTE );
  67. BEGIN
  68.     CommWrData(c);
  69.     INC( Sum, CARDINAL(SBITSET(c) * Parity) );
  70.     CRCchk := DoKCRC( ADR(c), 1, CRCchk  )
  71. END SendAndCheck;
  72.  
  73. BEGIN 
  74.     SendCount := Count;
  75.     SendSeq   := Seq;
  76.     SendType  := PType;
  77.     SendBuf   := Data;
  78.     WHILE CommRdData( 0 ) < ComAbort DO END; (* flush *)
  79.     Sum := 0;
  80.     CRCchk := 0;
  81.     CheckBytes := 1;
  82.     IF NOT(SendType IN CHARSET{'G', 'I', 'R', 'S'}) AND
  83.        NOT(RecvType IN CHARSET{'I', 'R', 'S'}) AND 
  84.        (TheirDefs.CheckType IN CHARSET{'2','3'}) THEN 
  85.          CheckBytes := SHORTCARD(TheirDefs.CheckType) - SHORTCARD('0')
  86.     END;
  87.     CommWrData( soh );
  88.     IF SendCount > 94 THEN 
  89.          SendAndCheck(20H);  (* long packet format *)
  90.     ELSE 
  91.          SendAndCheck( VAL(SHORTCARD, Count) + CheckBytes + 2 + 20H)
  92.     END;
  93.     SendAndCheck(Seq+20H);
  94.     SendAndCheck(PType);
  95.     IF SendCount > 94 THEN (* long packet format *)
  96.          SendAndCheck(SHORTCARD((SendCount+ORD(CheckBytes)) DIV 95)+20H);
  97.          SendAndCheck(SHORTCARD((SendCount+ORD(CheckBytes)) MOD 95)+20H);
  98.          SendAndCheck( SimpleCheck(Sum) );
  99.     END;
  100.     IF SendCount > 0 THEN
  101.          FOR i := 1 TO SendCount DO 
  102.               CommWrData(SendBuf^[i]);
  103.          END;
  104.          FOR i := 1 TO SendCount DO 
  105.               INC( Sum, CARDINAL(SBITSET(SendBuf^[i]) * Parity) );
  106.          END;
  107.          CRCchk := DoKCRC( SendBuf, SendCount, CRCchk );
  108.     END; (* Send Data *)
  109.     CASE CheckBytes OF
  110.          1: CommWrData( SimpleCheck(Sum) );   (* Checksum + 20H *)
  111.         |2: CommWrData( SHORTCARD((Sum >> 6) MOD 40H + 20H) );(*Bit 11-6*)
  112.             CommWrData( SHORTCARD(Sum MOD 40H) + 20H);(*Bit5-0*)
  113.         |3: CommWrData( SHORTCARD((CRCchk >> 12 ) MOD 10H) + 20H);
  114.             CommWrData( SHORTCARD((CRCchk >> 6  ) MOD 40H) + 20H);
  115.             CommWrData( SHORTCARD((CRCchk       ) MOD 40H) + 20H);
  116.     END; (* CASE *)
  117.     CommWrData(TheirDefs.EolChar); (* Cr *)
  118.     FOR i := 1 TO ORD(TheirDefs.NumPad)  DO
  119.          CommWrData(TheirDefs.PadChar);
  120.     END;
  121.     INC (DataRegisters[ FALSE, Packets ]);
  122.     DisplayData ( Packets, FALSE );
  123. END SendPacket;
  124.  
  125. PROCEDURE RecvPacket(): CHAR;
  126. (* Sets RecvCount, RecvSeq and RecvType, and fills RecvBuf^ *)
  127.  
  128.  VAR
  129.     i, Sum : CARDINAL;
  130.     CheckBytes,
  131.     Count,
  132.     InChar : SHORTCARD;
  133.     RecvOK : BOOLEAN;
  134.  
  135. PROCEDURE RdChar(VAR c: BYTE): BOOLEAN;
  136. VAR dat : CARDINAL;
  137. BEGIN
  138.     dat := CommRdData( ORD(TheirDefs.TimeOut) );
  139.     CASE dat OF
  140.     ComAbort: WHILE CommRdData( 0 ) < ComAbort DO END; (* flush *)
  141.             RecvType := '@';
  142. |ComTimedOut: RecvType := 'T'
  143.            ELSE c := VAL(BYTE, dat);
  144.                 RETURN TRUE
  145.     END;
  146.     RETURN FALSE
  147. END RdChar;
  148.  
  149. PROCEDURE ReceiveAndCheck( VAR c: BYTE ): BOOLEAN;
  150. BEGIN
  151.     IF NOT RdChar( c ) THEN
  152.          RETURN FALSE;
  153.     END;
  154.     INC( Sum, CARDINAL( SBITSET(c) * Parity) );
  155.     Sum := Sum MOD 4096;
  156.     CRCchk := DoKCRC( ADR(c), 1 , CRCchk );
  157.     RETURN TRUE
  158. END ReceiveAndCheck;
  159.  
  160. BEGIN
  161.     i := 0;
  162.     LOOP
  163.         CASE CommRdDataTest( ORD(TheirDefs.TimeOut) ) OF
  164.              soh: EXIT;
  165.        |ComAbort: WHILE CommRdData( 0 ) < ComAbort DO END; (* flush *)
  166.                   RecvType := '@';
  167.                   RETURN '@';
  168.     |ComTimedOut: RecvType := 'T';
  169.                   RETURN 'T';
  170.          END;
  171.          INC(i);
  172.          IF i >= PacketSize THEN
  173.               RecvType := 'T';
  174.               RETURN 'T'
  175.          END
  176.     END;
  177.  
  178.     Sum := 0;
  179.     CRCchk := 0;
  180.  
  181.     IF NOT ReceiveAndCheck( Count ) THEN
  182.          RETURN RecvType
  183.     END;
  184.     DEC( Count, 20H );
  185.     IF NOT ReceiveAndCheck( RecvSeq ) THEN
  186.          RETURN RecvType
  187.     END;
  188.     DEC( RecvSeq, 20H );
  189.     IF NOT ReceiveAndCheck( RecvType ) THEN
  190.          RETURN RecvType
  191.     END;
  192.  
  193.     CheckBytes := 1;
  194.     IF NOT (SendType IN CHARSET{'G', 'I', 'R', 'S'}) AND
  195.        NOT( RecvType IN CHARSET{'R', 'S'}) 
  196.        AND (CHR(TheirDefs.CheckType) IN CHARSET{'2','3'}) THEN 
  197.          CheckBytes := SHORTCARD(TheirDefs.CheckType) - SHORTCARD('0')
  198.     END;
  199.     IF Count = 0 THEN  (* Long Packet format *)
  200.          IF NOT ReceiveAndCheck( LENX1 ) THEN 
  201.               RETURN RecvType
  202.          END;
  203.          DEC( LENX1, 20H );
  204.          IF NOT ReceiveAndCheck( LENX2) THEN 
  205.               RETURN RecvType
  206.          END;
  207.          DEC( LENX2, 20H );
  208.          IF ( NOT RdChar(HCHECK) ) THEN
  209.               RETURN RecvType
  210.          END;
  211.          IF HCHECK <> SimpleCheck(Sum) THEN 
  212.               WHILE RdChar(HCHECK) DO END; (*Flush*)
  213.               RETURN RecvType
  214.          END;
  215.          INC( Sum, ORD(HCHECK) );
  216.          IF CheckBytes = 3 THEN  
  217.               CRCchk := DoKCRC( ADR(HCHECK), 1, CRCchk ) 
  218.          END;
  219.          RecvCount := (95* ORD(LENX1) ) + ORD(LENX2 - CheckBytes);
  220.     ELSE (* NOT Long Packet format *)
  221.          RecvCount := ORD(Count - 2 - CheckBytes);
  222.     END;
  223.     IF RecvCount >  0 THEN
  224.          FOR i := 1 TO RecvCount  DO (* Recv Data *)
  225.               IF NOT RdChar( RecvBuf^[i] ) THEN
  226.                    RETURN RecvType;
  227.               END;
  228.          END;
  229.          FOR i := 1 TO RecvCount  DO 
  230.               INC( Sum, CARDINAL(SBITSET(RecvBuf^[i]) * Parity) );
  231.          END;
  232.          Sum := Sum MOD 4096;
  233.          CRCchk := DoKCRC( RecvBuf, RecvCount, CRCchk );
  234.     END; (* Revc Data *)
  235.     CASE CheckBytes OF
  236.          1: RecvOK := RdChar(InChar) AND (InChar = SimpleCheck(Sum));
  237.         |2: RecvOK := RdChar(InChar) AND
  238.               (InChar - 20H = SHORTCARD(Sum >> 6) MOD 40H) (*Bit 11-6*)
  239.               AND RdChar(InChar) AND
  240.               (InChar - 20H = SHORTCARD( Sum MOD 40H) );  (*Bit5-0*)
  241.         |3: RecvOK := RdChar(InChar) 
  242.               AND (InChar = SHORTCARD((CRCchk >> 12 ) MOD 10H) + 20H)
  243.               AND RdChar(InChar) 
  244.               AND (InChar = SHORTCARD((CRCchk >> 6  ) MOD 40H) + 20H)
  245.               AND RdChar(InChar) 
  246.               AND (InChar = SHORTCARD((CRCchk       ) MOD 40H) + 20H);
  247.     END;  (* CASE CRC OR Checksum *)
  248.     INC (DataRegisters[ TRUE, Packets ]);
  249.     DisplayData ( Packets, TRUE );
  250.     IF RecvOK THEN
  251.          RETURN RecvType 
  252.     ELSE
  253.          RETURN 'Q'
  254.     END
  255. END RecvPacket;
  256.  
  257. PROCEDURE SendPacketType  (PacketType : BYTE);
  258. BEGIN (* Send ACK or NAK or B or Z *)
  259.     SendPacket( 0, (SendSeq+1) MOD 64, PacketType, NIL ); 
  260. END SendPacketType; (* Send ACK or NAK or B or Z *)
  261.  
  262. PROCEDURE SendDefaults( typ : CHAR );
  263. VAR i : CARDINAL;
  264. BEGIN
  265.     InitArray := InitArrayType(MyDefs);
  266.     IF typ <> 'Y' THEN
  267.          TheirDefs := MyDefs
  268.     ELSIF TheirDefs.RepChar <> ' ' THEN
  269.          INCL(MyExtControls, TheirDefs.RepChar);
  270.          INCL(MyExtControls, CHR(SHORTCARD(TheirDefs.RepChar)+80H));
  271.          InitArray[9] := SHORTCARD(TheirDefs.RepChar) 
  272.               (* Accept their repeat char *)
  273.     END;
  274.     FOR i := 1 TO 5 DO
  275.          INC(InitArray[i], 20H);
  276.     END;
  277.     FOR i := 10 TO SIZE(InitArray) DO
  278.          INC(InitArray[i], 20H);
  279.     END;
  280.     SendPacket( SIZE(InitArray), 0, typ, ADR(InitArray) );
  281. END SendDefaults;
  282.  
  283. PROCEDURE GetDefinitions;
  284. VAR i, j : CARDINAL; Capas : CapasType;
  285. BEGIN
  286.     i := RecvCount;
  287.     IF i > 5 THEN
  288.          i := 5
  289.     END;
  290.     FOR j := 1 TO i DO
  291.          DEC(RecvBuf^[j], 20H)
  292.     END;
  293.     IF RecvCount > 5 THEN 
  294.          INC(i)
  295.     END;
  296.     Move ( RecvBuf, ADR(TheirDefs), i );
  297.     MyExtControls := CHARSET{CHR(CtlChar), CHR(CtlChar+80H)};
  298.     Fill(ADR(TheirDefs.Bit8Quote), 3, 40C);
  299.          (* Fill with spaces Bit8Quote, CheckType, RepChar *)
  300.     IF (RecvCount >= 7) AND 
  301.       (CHR(RecvBuf^[7]) IN CHARSET{'!'..'?','`'..'~'}) THEN
  302.          TheirDefs.Bit8Quote := CHR(RecvBuf^[7]);
  303.          INCL(MyExtControls, TheirDefs.Bit8Quote );
  304.          INCL(MyExtControls, CHR(SHORTCARD(TheirDefs.Bit8Quote)+80H));
  305.          Parity := SevenBits;
  306.     ELSE 
  307.          Parity := EightBits;
  308.     END;
  309.     IF (RecvCount >= 8) AND (CHR(RecvBuf^[8]) IN CHARSET{'1'..'3'} ) THEN
  310.          IF CHR(RecvBuf^[8]) < MyDefs.CheckType THEN
  311.               TheirDefs.CheckType  := CHR(RecvBuf^[8])
  312.          ELSE
  313.               TheirDefs.CheckType  := MyDefs.CheckType 
  314.          END
  315.     ELSE 
  316.          TheirDefs.CheckType  := '1'
  317.     END;
  318.     IF RecvCount >= 9 THEN
  319.          IF (RecvType = 'Y') THEN
  320.               IF CHR(RecvBuf^[9]) = MyDefs.RepChar THEN
  321.                    TheirDefs.RepChar := MyDefs.RepChar;
  322.                    INCL(MyExtControls, TheirDefs.RepChar);
  323.                    INCL(MyExtControls, CHR(SHORTCARD(TheirDefs.RepChar)+80H));
  324.               END
  325.          ELSIF CHR(RecvBuf^[9]) IN CHARSET{'!'..'?','`'..'~'} THEN
  326.               TheirDefs.RepChar := CHR(RecvBuf^[9]);
  327.          END
  328.     END;
  329.     IF RecvCount >= 10 THEN
  330.          FOR j := 10 TO RecvCount DO
  331.               DEC(RecvBuf^[j], 20H)
  332.          END;
  333.          i := 10;
  334.          Capas := CapasType (RecvBuf^[10] )
  335.     ELSE 
  336.          Capas := CapasType {}
  337.     END;
  338.     IF i = 10 THEN       (* discard unknown Capas bytes *)
  339.          WHILE ODD(RecvBuf^[i])
  340.               DO INC(i)
  341.          END;
  342.          INC(i, 2);      (* skip last Capas, Windo bytes *)
  343.          IF (LongOK IN Capas) AND (RecvCount >= i+1) THEN
  344.               PacketSize := (ORD(RecvBuf^[i])-20H)*95 
  345.                    + ORD(RecvBuf^[i+1])-20H;
  346.               IF PacketSize > MaxPacketSize THEN
  347.                    PacketSize := MaxPacketSize 
  348.               END;
  349.          ELSE
  350.               PacketSize := ORD(TheirDefs.MaxLength)
  351.          END
  352.     ELSE
  353.          PacketSize := ORD(TheirDefs.MaxLength)
  354.     END;
  355. END GetDefinitions;
  356.  
  357. PROCEDURE InitDefinitions;
  358. BEGIN
  359.     PacketSize := 94; (*MaxPacketSize *)
  360.     TheirDefs := MyDefs;
  361.     Parity := EightBits;
  362. END InitDefinitions;
  363.  
  364. BEGIN
  365.     InitDefinitions;
  366. END QCkpack.
  367.